/*
 *  $Id: ArgPhrasePart.cs 1182 2010-11-10 16:23:57Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2010 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

namespace Ragima.Languages.PhraseParts {
    /// <summary>
    /// Часть фразы с аргументом.
    /// </summary>
    public class ArgPhrasePart : PhrasePart {
        private int _argNum;

        public ArgPhrasePart(int argNum) {
            _argNum = argNum;
        }

        /// <summary>
        /// Получает аргумент из массива. Возвращает null, если аргумент отсутствует.
        /// </summary>
        private object GetArg(object[] args) {
            return _argNum >= 0 && _argNum < args.Length ? args[_argNum] : null;
        }

        public override void Build(PhraseBuilder builder, object[] args) {
            var arg = GetArg(args);
            if (arg != null)
                BuildArg(builder, arg);
        }

        /// <summary>
        /// Строит аргумент как часть фразы.
        /// </summary>
        protected virtual void BuildArg(PhraseBuilder builder, object arg) {
            builder.Append(arg.ToString());
        }

        public override void BuildTemplate(PhraseBuilder builder) {
            builder.Text.Append(PhraseTemplateSymbols.CommandStart).Append(_argNum);
            BuildTemplateArg(builder);
            builder.Text.Append(PhraseTemplateSymbols.CommandEnd);
        }

        /// <summary>
        /// Строит аргумент как шаблон части фразы.
        /// </summary>
        protected virtual void BuildTemplateArg(PhraseBuilder builder) {}

        public override object GetHintObject(object[] args) {
            var arg = GetArg(args);
            if (arg != null)
                return GetHintObject(arg);
            else
                return base.GetHintObject(args);
        }

        /// <summary>
        /// Получает объект для хинта к части фразы по аргументу.
        /// </summary>
        /// <param name="arg">
        /// A <see cref="System.Object"/>
        /// </param>
        /// <returns>
        /// A <see cref="System.Object"/>
        /// </returns>
        protected virtual object GetHintObject(object arg) {
            return null;
        }

        /// <summary>
        /// Парсер для части фразы с аргументом.
        /// </summary>
        public sealed class ArgParser : IPhrasePartParser {
            public bool NeedArgument {
                get { return true; }
            }

            public bool Test(PhraseTemplateScanner scanner) {
                return true;
            }

            public PhrasePart Create(int argNum, PhraseTemplateScanner scanner) {
                return new ArgPhrasePart(argNum);
            }
        }
    }
}